﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#include "GcmpDatabase.h"
#include "OwnerPtr.h"
#include <string>
#include <vector>
#include "GbmpTypeDefs.h"

namespace gcmp
{
    class IDbObject;

    /// \brief IDbObject对象持久工具类
    ///
    /// 允许在永久的二进制形式上（通常为磁盘存储器）保存复杂的对象，并在对象被删除后（对象的生命周期结束被销毁）保持持久性。
    /// 之后，你可以从持久的存储器上加载这些对象并可在内存中重新构建他们。
    ///
    /// \note 只保证对同一个DbObject的同一个版本，Store之后再Load是成功的。
    ///       不保证不同版本之间的Store/Load，特别是从一个老版本文件中获取的数据。
    FINAL_INTERFACE class GCMP_DATABASE_EXPORT IDbObjectArchiveUtils
    {
    public:
        /// \brief 从buffer中加载对象
        ///
        /// \param buffer 对象数据
        /// \param[out] result 加载成功返回true；错误返回false
        /// \param[out] pErrorMessage 如果result返回false，在给定非空pErrorMessage时，pErrorMessage返回错误信息
        /// \return OwnerPtr<IDbObject> 加载承购
        static OwnerPtr<IDbObject> LoadDbObject(
            const std::vector<char> & buffer, 
            bool & result, 
            std::wstring * pErrorMessage = nullptr
        );

        /// \brief 将对象写入到buffer
        ///
        /// \param pDbObject 将要写入的对象。对象允许为空，此时什么都不做，返回true
        /// \param buffer 即将写入的数据，缓存首先会被清空。
        /// \param[out] pErrorMessage 如果函数返回false，在给定非空pErrorMessage时，pErrorMessage返回错误信息
        /// \return bool 写入成功返回true；错误返回false
        static bool StoreDbObject(
            const IDbObject * pDbObject, 
            std::vector<char> & buffer, 
            std::wstring * pErrorMessage = nullptr
        );

        /// \brief 判断body的最大长度是否大于给定的数据，如果载入的skp文件占内存过大，会在创建族实例的时候失败
        /// 后面skp导入做优化后，需要删除，如果不熟悉这块内容，请谨慎使用
        ///
        /// \param limitSize 要比较的数据，经验值1073741824，如果大于这个数据就返回true
        /// \param[out] 如果函数返回true，说明skp在导入的时候占内存大，有族载入失败的可能，可以提前阻止族的载入
        static bool CheckDataLengthIsGreaterThan(const UInt64& limitSize);

        /// \brief 设置拿到的最大的body长度，skp导入做优化后，需要删除
        ///
        /// \param objectLen body数据长度
        static void SetDataMaxLength(UInt64 objectLen);

        /// \brief 保存最大的body长度，skp导入做优化后，需要删除
        static UInt64 s_objectMaxLen;
    };
}

